using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;

namespace Deepcode.SchedulerService
{
	/// <summary>
	/// SchedulerConfig reads the scheduled tasks file and determines
	/// general configuration along with what tasks must be executed
	/// 
	/// <config timer="15">
	///		<task url="http://www.blah.com"/>
	/// </config>
	/// 
	/// </summary>
	public class SchedulerConfig
	{
		#region Members
		// The number of minutes between each execution of the task list
		private int _ExecutionMinutes = 15;

		// The filename of the tasks file to load
		private string FileName
		{
			get
			{
				return AppDomain.CurrentDomain.BaseDirectory + "NGTASKS.XML";
			}
		}
		
		// Determines the date and time that filename was last read
		private DateTime LastReadTime = new DateTime(1990, 1, 1);

		// Stores the list of tasks
		private List< Task > _TaskList = new List<Task>();

		// Holds reference to the event log
		private System.Diagnostics.EventLog EventLog = null;
		#endregion
		#region Exposed properties
		/// <summary>
		/// Get the number of minues between each execution of the task list
		/// </summary>
		public int ExecutionMinutes { get { return _ExecutionMinutes; } }
		#endregion

		/// <summary>
		/// Constructor - immediately loads the config
		/// </summary>
		public SchedulerConfig( System.Diagnostics.EventLog logger )
		{
			this.EventLog = logger;
			LoadConfiguration();
		}

		/// <summary>
		/// Set the configuration state to defaults and then attempt to load 
		/// the various tasks into the task list.
		/// </summary>
		public void LoadConfiguration()
		{
			// Default to 15 minutes with an empty task listing
			_ExecutionMinutes = 15;
			_TaskList = new List<Task>();

			// Ensure the file exists
			if (!File.Exists(this.FileName)) return;

			// Attempt to load the file as XML
			XmlDocument doc = new XmlDocument();
			try{ doc.Load(this.FileName); } catch { Debug("Could not XML Parse {0}", this.FileName); return; }
			
			// Prepare an XML Utility Service
			XmlUtilityService xu  = new XmlUtilityService();
			
			// Get the interval configuration
			_ExecutionMinutes = xu.GetSafe( doc.DocumentElement, "timer", 15 );

			// Find all of the task elements
			foreach (XmlNode node in doc.SelectNodes("/config/task"))
			{
				string ur = xu.GetSafe( node, "url", "" );
				if ((ur != null) && ur != (String.Empty))
				{
					Task t = new Task(ur);
					_TaskList.Add(t);
				}
			}

			LastReadTime = DateTime.Now;
		}
		
		/// <summary>
		/// Determines if the config needs reloading by interrogating 
		/// the last write time vs the last read time
		/// </summary>
		/// <returns></returns>
		public bool NeedsReload()
		{
			if( ! File.Exists(this.FileName) ) return false;
			if( File.GetLastWriteTime(this.FileName) > LastReadTime ) return true;
			return false;
		}

		/// <summary>
		/// Processes the task list
		/// </summary>
		public void ProcessTasks()
		{
			if (NeedsReload()) LoadConfiguration();
			foreach (Task t in _TaskList)
			{
				try
				{
					// Run the task and retrieve the response.
					System.Net.WebRequest request = System.Net.WebRequest.Create(t.URL);
					System.Net.WebResponse response = request.GetResponse();
					response.Close();
				}
				catch
				{
					Debug("TASK FAIL: {0}", t.URL);
				}
			}
		}

		/// <summary>
		/// Debug routine used to write text info to the event log
		/// </summary>
		/// <param name="db"></param>
		/// <param name="args"></param>
		private void Debug(string db, params object[] args)
		{
			string formatted = String.Format( db, args );
			EventLog.Source = "Flux.NET Scheduler";
			EventLog.WriteEntry( formatted, System.Diagnostics.EventLogEntryType.Information);
		}
	}
}
